import { _decorator, AudioClip, color, instantiate, log, mat4, Material, Node, Prefab, randomRangeInt, size, Sprite, Tween, tween, UIOpacity, UITransform, v2, v3, } from 'cc';
const { ccclass, property } = _decorator;

import { GameData } from "../Data/GameData";
import { BlockType, GameItem, GameState, PosType } from "../Data/GameEnum";
import Grid from "../Game/Grid";
import SS_NodeManager from "../Manager/SS_NodeManager";
import GamePanel from "../UI/GamePanel";
import Block from "../Game/Block";
import BlockGroup from "../Game/BlockGroup";
import Card from "../Game/Card";
import SS_AssetsManager from "../Manager/SS_AssetsManager";
import Board from "../Game/Board";
import SS_TimerManager from "../Manager/SS_TimerManager";
import StopBlock from "../Game/StopBlock";
import SS_MapManager from "../Manager/SS_MapManager";
import GameStorage from "../Data/GameStorage";
import SS_GameEventManager, { eventTarget, GameEventData } from "../Manager/SS_GameEventManager";
import { Consts } from "../Data/Consts";
import { bdlMgr } from "../Manager/SS_BundleManager";
import { MaterialData } from "../Config/MaterialData";
import TAComponent from "../sdk/TAComponent";
import AdMgr from "../utils/AdMgr";
import WaitingPanel from '../UI/WaitingPanel';
import SS_UIManager from '../Manager/SS_UIManager';
import { SS_AudioManager } from '../Manager/SS_AudioManager';
import { SS_Settings } from '../Data/SS_Settings';
import CommonFunction from '../utils/CommonFunction';
import SS_GameManager from '../Manager/SS_GameManager';
import SS_Line from '../Game/SS_Line';


@ccclass('CardFunctions')
export default class CardFunctions {
    static Get_col_by_x2(x_pos: number) {
        let w = 40;
        let x = (x_pos - (-GameData.W / 2 + w / 2)) / w + 0.5;
        let col = Math.floor(x);
        return col;
    }
    static Get_row_by_y2(y_pos: number) {
        let w = 40;
        let y = (y_pos - (-GameData.H / 2 + w / 2)) / w + 0.5;
        let row = Math.floor(y);
        return row;
    }

    static 判断是否在范围(pos1, pos2, width: number) {
        let x1 = Math.abs(pos2.x - pos1.x);
        let y1 = Math.abs(pos2.y - pos1.y);
        if (x1 < width && y1 < width) {
            return true;
        }

        return false;
    }


    static Get_col_by_x(x_pos: number) {
        let x = (x_pos - (-GameData.W / 2 + GameData.cell_width / 2)) / GameData.cell_width + 0.5;
        // let x = (x_pos - (-GameData.W / 2 + GameData.cell_width / 2)) / GameData.cell_width + 0;
        let col = Math.floor(x);
        // let col = x;
        return col;
    }
    static Get_row_by_y(y_pos: number) {
        let y = (y_pos - (-GameData.H / 2 + GameData.cell_height / 2)) / GameData.cell_width + 0.5;
        // let y = (y_pos - (-GameData.H / 2 + GameData.cell_height / 2)) / GameData.cell_width + 0;
        let row = Math.floor(y);
        return row;
    }
    static Get_x_by_col(col) {
        let x = -GameData.W / 2 + GameData.cell_width / 2 + GameData.cell_width * col;
        return x;
    }

    static Get_y_by_row(row) {
        let y = -GameData.H / 2 + GameData.cell_height / 2 + GameData.cell_height * row;
        return y;
    }

    //    /** 创建Emoji */
    static async CreateEmoji() {
        const Prefab_Emoji = await bdlMgr.getRes<Prefab>(Consts.BundleName.PREFAB, `Effect/Emoji`, Prefab);
        const node: Node = instantiate(Prefab_Emoji);
        SS_NodeManager.Instance.Root_effect.addChild(node);
        return node;
    }

    //    /** 创建格子 */
    static async CreateGrid(_id: number, x: number, y: number) {
        const Prefab_Grid = await bdlMgr.getRes<Prefab>(Consts.BundleName.PREFAB, `Grid`, Prefab);
        const node: Node = instantiate(Prefab_Grid);
        const scrGrid: Grid = node.getComponent(Grid);
        scrGrid.init(_id, x, y);
        SS_NodeManager.Instance.Root_grid.addChild(node);
        return scrGrid;
    }

    //    /** 创建牌组 */
    static async CreateBlock(_blockType: BlockType, _posType: PosType, _x: number, _y: number, _point: number, _color: number) {
        const Prefab_Block = await bdlMgr.getRes<Prefab>(Consts.BundleName.PREFAB, `Block`, Prefab);
        const node: Node = instantiate(Prefab_Block);
        const block: Block = node.getComponent(Block);
        GamePanel.Instance.GeneratePoint_blook_list[_x].addChild(node);
        block.init(_blockType, _posType, _x, _y, _point, _color);
        return block;
    }

    //    /**  */
    static async CreateStopBlock(_x: number, _y: number, _type) {
        const Prefab_StopBlock = await bdlMgr.getRes<Prefab>(Consts.BundleName.PREFAB, `StopBlock`, Prefab);
        const node: Node = instantiate(Prefab_StopBlock);
        const stopBlock: StopBlock = node.getComponent(StopBlock);
        SS_NodeManager.Instance.Root_grid.addChild(node);
        stopBlock.Init(_x, _y, _type);
        GameData.arrStopBlock.push(stopBlock);
        return stopBlock;
    }
    //    /** 创建牌组 */
    static async CreateBlockGroup(_x: number, _y: number, _id, _color: number, posType: PosType) {
        const Prefab_BlockGroup = await bdlMgr.getRes<Prefab>(Consts.BundleName.PREFAB, `BlockGroup`, Prefab);
        const node: Node = instantiate(Prefab_BlockGroup);

        const blockGroup: BlockGroup = node.getComponent(BlockGroup);
        // GamePanel.Instance.GeneratePoint_blook_list[_x].addChild(node);
        SS_NodeManager.Instance.GeneratePoint_blook.addChild(node);
        node.position = GamePanel.Instance.GeneratePoint_blook_list[_x].position;

        blockGroup.init(_x, _y, _id, _color, posType);
        // GameData.arrCardGroups.push(blockGroup);
        GameData.arrCardGroups[_x] = blockGroup;
        return blockGroup;
    }
    //    /** 创建牌组 */
    static async CreateBlockGroup_temp(_x: number, _y: number, _id, _color: number, posType: PosType) {
        const Prefab_BlockGroup = await bdlMgr.getRes<Prefab>(Consts.BundleName.PREFAB, `BlockGroup`, Prefab);
        const node: Node = instantiate(Prefab_BlockGroup);

        const blockGroup: BlockGroup = node.getComponent(BlockGroup);
        GamePanel.Instance.GeneratePoint_blook_list_temp[_x].addChild(node);
        blockGroup.init(_x, _y, _id, _color, posType);
        blockGroup.node.active = false;
        // GameData.arrCardGroups_temp.push(blockGroup);
        GameData.arrCardGroups_temp[_x] = blockGroup;
        return blockGroup;
    }

    //    // tetrisType
    static async 随机创建一个BlockGroup(index) {
        // let Level_data = Levels[GameData.CurrentLevel].d;

        let Level_data = GameData.Get_LevelData_down();

        GameData.arrCardGroups_temp[index] = null;
        GameData.arrCardGroups[index] = null;

        if (GameData.currentBlockGroupCreateIndex >= Level_data.length) {
            return;
        }

        let item_data = Level_data[GameData.currentBlockGroupCreateIndex];
        // console.log("item_data", item_data);

        let x = index;
        let y = -1;
        let id = item_data.c;
        let tetrisType = item_data.t;
        let posType = PosType.下面操作台中;

        CardFunctions.CreateBlockGroup_temp(x, y, id, tetrisType, posType);

        const blockGroup: BlockGroup = await CardFunctions.CreateBlockGroup(x, y, id, tetrisType, posType);

        GameData.currentBlockGroupCreateIndex++;


        let d1 = 500;
        let d2 = 4;
        // blockGroup.node.y -= d1;
        let p = blockGroup.node.position;
        blockGroup.node.setPosition(p.x, p.y - d1, p.z);

        tween(blockGroup.node)
            .by(0.4, { position: v3(0, d1 + d2) })
            .by(0.1, { position: v3(0, -d2) })
            // .by(0.4, { y: +(d1 + d2) }, { easing: "" })
            // .by(0.1, { y: -d2 }, { easing: "" })
            .call(() => {
            })
            .start();
        await SS_TimerManager.AwaitTime(0.02);
    }

    static async 创建下一个BlockGroup() {
        if (GameData.Current_next_BlockGroup) {
            GameData.Current_next_BlockGroup.node.destroy();
            GameData.Current_next_BlockGroup = null;
        }

        let Level_data = GameData.Get_LevelData_down();
        let next_id = GameData.currentBlockGroupCreateIndex;
        if (next_id >= Level_data.length) {
            GamePanel.Instance.下一个俄罗斯方块.parent.active = false;
        }
        else {
            GamePanel.Instance.下一个俄罗斯方块.parent.active = true;

            CardFunctions.防止三个一样的特殊交换();

            let item_data = Level_data[next_id];

            const Prefab_BlockGroup = await bdlMgr.getRes<Prefab>(Consts.BundleName.PREFAB, `BlockGroup`, Prefab);
            const node: Node = instantiate(Prefab_BlockGroup);
            const blockGroup: BlockGroup = node.getComponent(BlockGroup);
            GamePanel.Instance.下一个俄罗斯方块.addChild(node);

            let x = 1;
            let y = -1;
            let id = item_data.c;
            let tetrisType = item_data.t;
            let posType = PosType.下面操作台中;

            blockGroup.init(x, y, id, tetrisType, posType);
            node.position = v3(0, 0, 0);
            node.setScale(0.5, 0.5, 0.5);
            GameData.Current_next_BlockGroup = blockGroup;

            blockGroup.RemoveListener()

            return blockGroup;
        }
    }

    //    /** 创建Card */
    static async CreateCard(_x: number, _y: number, _id) {
        const Prefab_Card = await bdlMgr.getRes<Prefab>(Consts.BundleName.PREFAB, `Card`, Prefab);
        const node: Node = instantiate(Prefab_Card);
        const card: Card = node.getComponent(Card);
        SS_NodeManager.Instance.Root_grid.addChild(node);
        card.Init(_x, _y, _id);
        // GameData.arrCards.push(card);
        return card;
    }

    static GetCardId() {
        let keys = Object.keys(GameItem);
        let random: number = randomRangeInt(0, keys.length);
        let id = keys[random];
        return id;
    }

    //    /** 创建Board */
    static async CreateBoard(_x: number, _y: number, layer: number, _layout: any, _cardList: any) {
        const Prefab_Board = await bdlMgr.getRes<Prefab>(Consts.BundleName.PREFAB, `Board`, Prefab);
        const node: Node = instantiate(Prefab_Board);
        const board: Board = node.getComponent(Board);
        SS_NodeManager.Instance.Root_board.addChild(node);
        board.Init(_x, _y, layer, _layout, _cardList);
        GameData.arrBoard.push(board);
        return board;
    }

    //    /** 创建Bomb */
    static async CreateBomb(pos) {
        const Prefab_Bomb = await bdlMgr.getRes<Prefab>(Consts.BundleName.PREFAB, `Effect/Bomb`, Prefab);
        const node: Node = instantiate(Prefab_Bomb);
        SS_NodeManager.Instance.Root_effect.addChild(node);

        // let p1 = target.convertToWorldSpaceAR(v3(0, 0, 0));
        // let p2 = node.parent.convertToNodeSpaceAR(p1);
        // node.position = p2;

        let p1 = pos;
        let p2 = node.parent.getComponent(UITransform).convertToNodeSpaceAR(p1);
        node.position = p2;

        // let p1 = block.node.worldPosition;
        // let p2 = NodeManager.Instance.Root_grid.getComponent(UITransform).convertToNodeSpaceAR(p1);
        // let pos1 = grid.node.worldPosition;
        // let pos2 = block.node.parent.getComponent(UITransform).convertToNodeSpaceAR(pos1);
        // block.node.position = pos2;

        return node;
    }

    static GetGrid(x: number, y: number) {
        if (GameData.arrGrids[x] && GameData.arrGrids[x][y]) {
            return GameData.arrGrids[x][y];
        }

        return null;
    }

    static GetCard(col, row) {
        let card: Card = GameData.arrCards.find(e => (e.col === col && e.row === row));
        return card;
    }

    static GetStopBlock(x: number, y: number) {
        let stopBlock: StopBlock = GameData.arrStopBlock.find(e => (e.col === x && e.row === y));
        return stopBlock;
    }

    static Get_arrCardGroups() {
        return GameData.arrCardGroups;
    }

    static Get_arrCardGroup_grid() {
        // const arr = GameData.arrCardGroups.filter(number => number.posType === PosType.方格中);
        // return arr;
        return GameData.arrBlockGroup_M;
    }

    //    /** 获取随机颜色 */
    static GetRandomId() {
        let id: number = randomRangeInt(0, 3);
        return id;
    }

    //    /** 获取俄罗斯方块类型 */
    static Get_tetrisType() {
        // let id: number = randomRangeInt(0, 9);
        // let id: number = 0;
        let id: number = randomRangeInt(0, 3);

        return id;
    }

    //    /** 获取随机颜色 */
    static GetRandomColor() {
        let color: number = randomRangeInt(0, 4);
        return color;
    }

    //    /** 获取随机点数 */
    static GetRandomPoint() {
        let point: number = randomRangeInt(1, 6 + 1);
        return point;
    }

    //    /**  */
    static IsCardId(_id) {
        if (_id && Math.abs(_id) > 0) {
            return true;
        }
        else {
            return false;
        }
    }
    //    // 获取Item
    static GetItem(arr, x: number, y: number) {
        if (arr[x] && arr[x][y]) {
            return arr[x][y];
        }

        return null;
    }

    //    // 
    static SetAllGridCanPlaceByBlock(block_target: Block) {
        for (let x = 0; x < GameData.col; x++) {
            for (let y = 0; y < GameData.row; y++) {
                const grid_0: Grid = CardFunctions.GetGrid(x, y);
                if (grid_0.block) {
                    grid_0.canPlace = false;
                }

                let up: Grid = CardFunctions.GetGrid(x, y + 1);
                let down: Grid = CardFunctions.GetGrid(x, y - 1);
                let left: Grid = CardFunctions.GetGrid(x - 1, y);
                let right: Grid = CardFunctions.GetGrid(x + 1, y);

                let array = [up, down, left, right];
                for (let index = 0; index < array.length; index++) {
                    const grid_4: Grid = array[index];
                    if (block_target && grid_4 && grid_4.block) {
                        if (block_target.color !== grid_4.block.color && block_target.point !== grid_4.block.point) {
                            grid_0.canPlace = false;
                        }
                    }
                }
            }
        }
    }

    static RefreshAllGridCanPlace() {
        for (let x = 0; x < GameData.col; x++) {
            for (let y = 0; y < GameData.row; y++) {
                const grid_0: Grid = CardFunctions.GetGrid(x, y);
                if (grid_0) {
                    grid_0.RefreshPlace();
                }
            }
        }
    }

    static SetAllGridCanPlaceForce(active: boolean) {
        for (let x = 0; x < GameData.col; x++) {
            for (let y = 0; y < GameData.row; y++) {
                const grid_0: Grid = CardFunctions.GetGrid(x, y);
                if (grid_0) {
                    grid_0.canPlace = active;
                    grid_0.RefreshPlace();
                }
            }
        }
    }

    static 当前格子是否是空地(x, y) {
        let grid: Grid = CardFunctions.GetGrid(x, y)
        let stopBlock = CardFunctions.GetStopBlock(x, y)

        if (grid && grid.block === null && !stopBlock) {
            return true;
        }
        else {
            return false;
        }
    }

    //    // 
    static AllGridSelect(active: boolean) {
        for (let x = 0; x < GameData.col; x++) {
            for (let y = 0; y < GameData.row; y++) {
                const grid: Grid = CardFunctions.GetGrid(x, y);
                grid.Select(active);
            }
        }
    }

    //    // 是否存在Grid
    static HasGrid(x: number, y: number): boolean {
        if (GameData.arrGrids[x] && GameData.arrGrids[x][y] && GameData.arrGrids[x][y].id >= 0) {
            return true;
        } else {
            return false;
        }
    }

    //    // 获取比指定Board层高的
    public static GetHighLayerBoardArray(_board: Board) {
        const array = [];
        for (let index = 0; index < GameData.arrBoard.length; index++) {
            const board = GameData.arrBoard[index];
            if (board.layer > _board.layer) {
                array.push(board);
            }
        }

        // console.log("array", array);

        return array;
    }

    //    // 指定Board是否被遮挡
    public static IsBoardCover(_board: Board) {
        const array = CardFunctions.GetHighLayerBoardArray(_board);
        for (let index = 0; index < array.length; index++) {
            const board = array[index];
            if (_board !== board) {
                let isBanana = CardFunctions.IsBanana(_board, board);
                if (isBanana) {
                    return true;
                }
            }
        }

        return false;
    }

    //    // 是否相交
    public static IsBanana(b1: Board, b2: Board): boolean {
        let w = (b1.w + b2.w) * 0.5;
        let h = (b1.h + b2.h) * 0.5;
        let x = Math.abs(b1.node.position.x - b2.node.position.x);
        let y = Math.abs(b1.y - b2.y);
        // let y = Math.abs(b1.node.position.y - b2.node.position.y);

        if (x < w && y < h) {
            return true;
        }

        return false;
    }

    //    // 设置所有卡片覆盖
    public static SetAllBoardCover() {
        for (let index = 0; index < GameData.arrBoard.length; index++) {
            const board = GameData.arrBoard[index];
            board.SetCover();
        }
    }

    //    // 
    public static GetAllItemArray() {
        let array = [];

        let data_up = GameData.Get_LevelData_up();
        for (let index = 0; index < data_up.length; index++) {
            let data_layer = data_up[index];
            for (let _layer = 0; _layer < data_layer.length; _layer++) {
                const item_data_c = data_layer[_layer].c;
                // console.log("item_data_c", item_data_c);

                for (let index = 0; index < item_data_c.length; index++) {
                    const id = item_data_c[index];
                    if (id > 0) {
                        const find_item = array.find(element => element.id === id);
                        if (find_item) {
                            find_item.count++;
                        }
                        else {
                            let item = { id: id, count: 1 };
                            array.push(item);
                        }
                    }
                }
            }
        }

        // console.log("GetAllItemArray", array);

        return array;
    }
    //    // 
    public static 生成id俄罗斯方块(_count) {
        let arr = [];

        while (_count > 0) {
            const array = CardFunctions.Get_tetrisCountArray_less(_count);
            // console.log("生成id俄罗斯方块", array);

            let random = randomRangeInt(0, array.length);
            let item = array[random];
            let count = item.count;


            //如果是1，降低概率
            if (count === 1) {
                let r1 = randomRangeInt(0, 100);
                // if (r1 < 90) {
                random = randomRangeInt(0, array.length);
                item = array[random];
                count = item.count;
                // }
            }


            arr.push(item);
            _count -= count;
        }

        // console.log("生成id俄罗斯方块-arr", arr);

        return arr;
    }
    //    // 
    public static GetAllBlockGroup() {
        //        // let array = [];

        let array = CardFunctions.GetAllItemArray();

        for (let index = 0; index < array.length; index++) {
            const item = array[index];
            // console.log("item", item);

            let arr = CardFunctions.生成id俄罗斯方块(item.count);
            // console.log(arr);

            for (let index = 0; index < arr.length; index++) {
                const element = arr[index];
                GameData.currentLevelData_d.push({
                    t: element.tetris_id,
                    c: item.id,
                });
            }
        }

        // console.log("GameData.currentLevelData_d", GameData.currentLevelData_d);

        return array;
    }
    //    // 获取方块的数量
    public static Get_tetrisCount(_id) {
        const item = GameData.TetrisData.find(e => e.tetris_id === _id);
        if (item) {
            return item.count;
        }

        return 0;
    }
    //    // 获取方块的数量=count的方块数组
    public static Get_tetrisCountArray(_count) {
        const array = GameData.TetrisData.filter(e => e.count === _count);
        if (array && array.length && array.length > 0) {
            return array;
        }

        return [];
    }

    //    // 获取方块的数量<=count的方块数组
    public static Get_tetrisCountArray_less(_count) {
        const array = GameData.TetrisData.filter(e => e.count <= _count);
        if (array && array.length && array.length > 0) {
            return array;
        }

        return [];
    }

    //    // 洗牌算法
    public static ShuffleArray(array) {
        for (let i = array.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [array[i], array[j]] = [array[j], array[i]];
        }
        return array;
    }

    static 是否可以放得下() {
        let null_count = 0;

        for (let index_arrCardGroups_temp = 0; index_arrCardGroups_temp < GameData.arrCardGroups_temp.length; index_arrCardGroups_temp++) {
            const group1 = GameData.arrCardGroups_temp[index_arrCardGroups_temp];

            if (group1) {
                group1.node.setScale(1, 1, 1);
                for (let index_1 = 0; index_1 < 4; index_1++) {
                    group1.node.angle += 90;

                    for (let x = 0; x < GameData.col; x++) {
                        for (let y = 0; y < GameData.row; y++) {
                            const grid: Grid = CardFunctions.GetGrid(x, y);

                            // let p1 = grid.node.convertToWorldSpaceAR(v3(0, 0))
                            let p1 = grid.node.worldPosition;

                            let block1 = group1.block_list[0];
                            let p2 = block1.node.parent.getComponent(UITransform).convertToNodeSpaceAR(p1);

                            let arrdiff = [];

                            for (let index = 0; index < group1.block_list.length; index++) {
                                const block = group1.block_list[index];
                                // let diff_pos = v3(block.node.x - block1.node.x, block.node.y - block1.node.y, 0);
                                let diff_pos = v3(block.node.position.x - block1.node.position.x, block.node.position.y - block1.node.position.y, 0);
                                arrdiff.push(diff_pos);
                            }

                            for (let index = 0; index < group1.block_list.length; index++) {
                                const block = group1.block_list[index];
                                let diff_pos = arrdiff[index];
                                let pos_new = v3(p2.x + diff_pos.x, p2.y + diff_pos.y);
                                block.node.position = pos_new;
                            }

                            let is是否契合 = CardFunctions.是否契合(group1);
                            if (is是否契合) {
                                return true;
                            }
                        }
                    }
                }
            }
            else {
                null_count++;
            }
        }

        console.log("null_count-----------------", null_count);
        console.log("GameData.arrCardGroups_temp.length-----------------", GameData.arrCardGroups_temp.length);

        if (null_count === GameData.arrCardGroups_temp.length) {
            console.log("是否可以放得下-----------------", true);

            return true;
        }

        console.log("是否可以放得下-----------------", false);

        return false;
    }

    static 是否契合(group1) {
        let count = 0;
        for (let index = 0; index < group1.block_list.length; index++) {
            const block: Block = group1.block_list[index];
            // let p1 = block.node.convertToWorldSpaceAR(v2(0, 0));
            // let p2 = NodeManager.Instance.Root_grid.convertToNodeSpaceAR(p1);
            let p1 = block.node.worldPosition;
            let p2 = SS_NodeManager.Instance.Root_grid.getComponent(UITransform).convertToNodeSpaceAR(p1);
            const x_new = block.GetXByX(p2.x);
            const y_new = block.GetXByY(p2.y);

            let 当前格子是否是空地 = CardFunctions.当前格子是否是空地(x_new, y_new);
            if (当前格子是否是空地) {
                count++;
            }
        }

        if (count === group1.block_list.length) {
            return true;
        }

        return false;
    }

    static 连击() {
        CardFunctions.计算连击index();
        CardFunctions.播放连击音效();
        CardFunctions.播放连击动画();
    }
    static 计算连击index() {
        if (GameData.连击count !== null) {
            let time2 = new Date().getTime();
            let diff_time = time2 - GameData.连击time;

            let 连击时间间隔 = 1000; //500
            let 连击时间间隔_累计 = 连击时间间隔 * (GameData.连击count);
            if (diff_time <= 连击时间间隔_累计) {
                GameData.连击count++;
                if (GameData.连击count > 8) {
                    GameData.连击count = 8;
                }
            }
            else {
                GameData.连击count = 1;
                GameData.连击time = new Date().getTime();
            }
        }
        else {
            GameData.连击count = 1;
            GameData.连击time = new Date().getTime();
        }
    }
    static async 播放连击音效() {
        if (GameData.连击count) {
            bdlMgr.getRes<AudioClip>(Consts.BundleName.AUDIO, `sound/消除${GameData.连击count}`, AudioClip).then(async (audio) => {
                SS_AudioManager.Instance.playOneShot(audio, SS_Settings.curMusicV);
            });
        }
    }

    static tween_连击;
    static 播放连击动画() {
        if (GameData.连击count && GameData.连击count >= 2) {
            GamePanel.Instance.Label_连击.string = `${GameData.连击count}`;

            const node = GamePanel.Instance.连击;
            node.active = true;
            node.setScale(1, 1, 1);
            node.getComponent(UIOpacity).opacity = 255;

            // CardFunctions.tween_连击?.stop();
            // CardFunctions.tween_连击 = tween(node)
            //     .to(0.2, { scale: v3(1.6, 1.6, 1.6) })
            //     .to(0.2, { scale: v3(1, 1, 1) })

            //     .call(() => {
            //         node.active = false;
            //     })
            //     .start();

            CardFunctions.tween_连击?.stop();

            let t1 = tween(node)
                .to(0.2, { scale: v3(1.6, 1.6, 1.6) })

            let t2 = tween(node)
                .to(0.2, { scale: v3(1, 1, 1) })

            let t3 = tween(node.getComponent(UIOpacity))
                .to(1, { opacity: 0 })
                .call(() => {
                    node.active = false;
                })

            CardFunctions.tween_连击 = tween(node).sequence(t1, t2, t3).start(); // 将 t1 和 t2 两个缓动加入到新的缓动队列内
        }
    }

    static 获取上桌数据() {
        let data = [];

        let arrCardGroup_grid = CardFunctions.Get_arrCardGroup_grid()
        // console.log("arrCardGroup_grid", arrCardGroup_grid);

        // GameData.arrBoard.sort((a, b) => a.GetLength() - b.GetLength());
        let copy_arrBoard = GameData.arrBoard.concat();
        copy_arrBoard.sort((a, b) => a.GetLength() - b.GetLength());

        for (let index2 = 0; index2 < arrCardGroup_grid.length; index2++) {
            const blockGroup: BlockGroup = arrCardGroup_grid[index2];
            for (let index_block = 0; index_block < blockGroup.block_list.length; index_block++) {
                const block: Block = blockGroup.block_list[index_block];
                for (let index_board = 0; index_board < copy_arrBoard.length; index_board++) {
                    const board: Board = copy_arrBoard[index_board];
                    // console.log("board", board);
                    // console.log("board.cardList", board.cardList);

                    for (let index_card = 0; index_card < board.cardList.length; index_card++) {
                        const card: Card = board.cardList[index_card];

                        // console.log(`card`, card);
                        // console.log(`card.node`, card.node);
                        // console.log(`card.id`, card.id);
                        // console.log(`block.id`, block.id);
                        const isBoardCover = CardFunctions.IsBoardCover(board);

                        if (card && block && card.id === block.id && block.is装填 === false && !isBoardCover) {
                            block.is装填 = true;
                            // card.is装填 = true;

                            data.push({
                                card: card,
                                block: block,
                                blockGroup: blockGroup,
                            })
                        }
                    }
                }
            }
        }

        return data;
    }

    static 获取撤凳子数据() {
        let data = [];

        // let arrCardGroup_grid = CardFunctions.Get_arrCardGroup_grid()

        for (let index = 0; index < GameData.arrBoard.length; index++) {
            const board: Board = GameData.arrBoard[index];
            let is撤凳子 = board.Check撤凳子();
            // console.log("is撤凳子", is撤凳子);

            if (is撤凳子) {
                // GameData.撤凳子list.push(board);
                data.push(board);
            }
        }

        return data;
    }

    static async 随机方块() {
        {
            let array_card = [];

            for (let index = 0; index < GameData.arrBoard.length; index++) {
                const board: Board = GameData.arrBoard[index];
                for (let index2 = 0; index2 < board.cardList.length; index2++) {
                    const card: Card = board.cardList[index2];
                    if (card.id > 0 === false) {
                        array_card.push(card)
                    }
                }
            }

            for (let index = 0; index < 100; index++) {
                const card1: Card = array_card[randomRangeInt(0, array_card.length)];
                const card2: Card = array_card[randomRangeInt(0, array_card.length)];

                [card1.id, card2.id] = [card2.id, card1.id]

                card1.Refresh2();
                card2.Refresh2();
            }

            CardFunctions.保证一个方块有解();
        }

        await SS_MapManager.Instance.开场动画_up();

        SS_GameEventManager.拖拽完成();
    }

    static async 摧毁方块() {
        let array = GameData.arrStopBlock.filter(x => x.type === 1)
        if (array && array.length > 0) {
            let block = array[0];
            block.Destroy();

            let bomb = await CardFunctions.CreateBomb(block.node.worldPosition);
            // let p1 = block.node.convertToWorldSpaceAR(cc.v3(0, 0, 0));
            // let p2 = bomb.parent.convertToNodeSpaceAR(p1);
            // bomb.position = p2;

            bdlMgr.getRes<AudioClip>(Consts.BundleName.AUDIO, `sound/烟雾消散`, AudioClip).then(audio => {
                SS_AudioManager.Instance.playOneShot(audio, SS_Settings.curMusicV);
            });

            await SS_TimerManager.AwaitTime(0.21);
            bomb.destroy();
        }
    }

    static 获取当前一共多少层() {
        let layer = 0;
        for (let index = 0; index < GameData.arrBoard.length; index++) {
            const board: Board = GameData.arrBoard[index];
            if (layer < board.layer) {
                layer = board.layer;
            }
        }
        return layer;
    }

    static 保证一个方块有解() {
        let new_arrCardGroups = [];
        for (let index = 0; index < GameData.arrCardGroups.length; index++) {
            const blockGroup = GameData.arrCardGroups[index];
            if (blockGroup) {
                new_arrCardGroups.push(blockGroup);
            }
        }

        let array = GameData.arrBlockGroup_M.concat(new_arrCardGroups);

        // console.log("array", array);
        // console.log("array.length", array.length);

        let layer = CardFunctions.获取当前一共多少层();
        // console.log("layer", layer);

        let l1 = GameData.arrBoard.filter(x => x.layer === layer)
        let b = l1[0]
        let card1 = b.GetCard1()

        let id = array[0].id
        // console.log("id", id);

        let card2 = CardFunctions.GetCard_by_id(id);
        // console.log("card2", card2);

        [card1.id, card2.id] = [card2.id, card1.id]
        card1.Refresh2();
        card2.Refresh2();
    }

    static GetCard_by_id(_id) {
        // console.log("GameData.arrBoard", GameData.arrBoard);

        for (let index = 0; index < GameData.arrBoard.length; index++) {
            const board: Board = GameData.arrBoard[index];
            for (let index2 = 0; index2 < board.cardList.length; index2++) {
                const card: Card = board.cardList[index2];
                // console.log("_id", card.id, _id, card.is装填);

                if (card.id > 0) {
                    // console.log("card", card);
                    return card;
                }
            }
        }
    }

    static 获取解锁格子记录() {
        let item = GameStorage.data.unlock_map.find(x => x.level === GameData.CurrentLevel);
        if (item) {
        }
        else {
            item = {
                level: GameData.CurrentLevel,
                unlock: [false, false]
            }
            GameStorage.data.unlock_map.push(item)
        }

        return item;
    }

    static async PlayShowWujin() {
        bdlMgr.getRes<AudioClip>(Consts.BundleName.AUDIO, `sound/无尽模式`, AudioClip).then(audio => {
            SS_AudioManager.Instance.playOneShot(audio, SS_Settings.curMusicV);
        });

        GamePanel.Instance.无尽模式开场动画.active = true;
        await SS_TimerManager.AwaitTime(2);
        GamePanel.Instance.无尽模式开场动画.active = true;
    }

    static async PlayGuide_1() {
        const node = GamePanel.Instance.引导手_拖拽

        if (GamePanel.Instance.GeneratePoint_blook_list && GamePanel.Instance.GeneratePoint_blook_list[0]) {
            let w1 = GamePanel.Instance.GeneratePoint_blook_list[0].worldPosition;
            let p1 = node.parent.getComponent(UITransform).convertToNodeSpaceAR(w1);

            let w2 = SS_NodeManager.Instance.Root_grid.worldPosition;
            let p2 = node.parent.getComponent(UITransform).convertToNodeSpaceAR(w2);

            GamePanel.Instance.tween_引导手 = tween(node)
                .repeatForever(
                    tween()
                        .call(() => {
                            node.position = p1;
                            node.active = true;
                        })
                        .to(1, { position: p2 })
                        .delay(0.4)
                )
            GamePanel.Instance.tween_引导手.start();
        }
    }

    static StopGuide_1() {
        const node = GamePanel.Instance.引导手_拖拽;
        Tween.stopAllByTarget(node);
        node.active = false;
    }

    static async PlayGuide_2() {
        const node = GamePanel.Instance.引导手_点击旋转;

        if (GamePanel.Instance.GeneratePoint_blook_list && GamePanel.Instance.GeneratePoint_blook_list[1]) {
            let w1 = GamePanel.Instance.GeneratePoint_blook_list[0].worldPosition;
            let p1 = node.parent.getComponent(UITransform).convertToNodeSpaceAR(w1);
            node.position = p1;
            node.active = true;
        }
    }

    static StopGuide_2() {
        GamePanel.Instance.引导手_点击旋转.active = false;
    }

    static GetAll空格子() {
        let array = [];

        for (let index = 0; index < GameData.arrBlockGroup_M.length; index++) {
            const blockGroup = GameData.arrBlockGroup_M[index];

            for (let index2 = 0; index2 < blockGroup.block_list.length; index2++) {
                const block = blockGroup.block_list[index2];
                if (!block.is装填) {
                    let scale = block.node.scale;
                    let newscale = v3(scale.x + 0.1, scale.y + 0.1, scale.z + 0.1);
                    block.node.setScale(newscale);

                    array.push(block.id);
                }
            }
        }

        return array;
    }

    static 获取实际y(board: Board) {
        return CardFunctions.GetLayerYOffset(board.layer);
    }
    static GetLayerYOffset(_layer) {
        return _layer * GameData.Offset_y_each_layer;
    }

    static 生成无尽模式数据() {
        let array_id = CardFunctions.获取不重复的n种itemid(5);
        // console.log("array_id", array_id);

        let copyLevels = SS_AssetsManager.Levels.concat();

        let array = [];
        for (let index = 0; index < copyLevels.length; index++) {
            const Level_u = copyLevels[index].u;
            // console.log("Level", Level);

            for (let index_2 = 0; index_2 < Level_u.length; index_2++) {
                const layer = Level_u[index_2];
                // console.log("layer", layer);
                // console.log("array[index_2]", array[index_2]);

                if (!array[index_2]) {
                    array[index_2] = [];
                }
                array[index_2].push(layer);

                // array.push(layer);
            }
        }

        // console.log("array", array);

        // 上面board数据
        let layer_count = CardFunctions.获取当前无尽关卡的层数(GameData.Get_CurrentLevel()); // 7;
        let u = [];
        for (let index = 0; index < layer_count; index++) {
            let layer_data = array[index];
            const random = randomRangeInt(0, layer_data.length);
            let data = layer_data[random];
            // console.log("data", data);

            for (let index2 = 0; index2 < data.length; index2++) {
                let item_data = data[index2];
                let c = item_data.c;
                // console.log("c", c);

                for (let index3 = 0; index3 < c.length; index3++) {
                    let item_c = c[index3];
                    // console.log("item_c", item_c);

                    let random_id_index = randomRangeInt(0, array_id.length);
                    let random_id = array_id[random_id_index];
                    c[index3] = random_id;
                }
            }

            u.push(data);
        }

        // console.log("u", u);


        // 中间阻挡数据
        let stop_count = CardFunctions.获取当前无尽关卡的阻挡数(GameData.Get_CurrentLevel()); // 012;
        let m = null;
        if (stop_count > 0) {
            m = [];
            while (stop_count > 0) {
                let random_x = randomRangeInt(0, GameData.col - 1);
                let random_y = randomRangeInt(0, GameData.row);
                let item = { x: random_x, y: random_y };
                let findItem = m.find(e => e.x === item.x && e.y === item.y);
                if (!findItem) {
                    m.push(item);
                    stop_count--;
                }
            }
        }


        GameStorage.data.wujin_data = {};
        GameStorage.data.wujin_data.u = u;
        GameStorage.data.wujin_data.m = m;
        GameStorage.data.wujin_data.level = GameData.Get_CurrentLevel();

        GameStorage.saveData();
    }

    static 获取不重复的n种itemid(_number = 5) {
        let array = [];

        let copy_itemList = MaterialData.concat();

        while (_number > 0) {
            let random = randomRangeInt(0, copy_itemList.length);
            let item = copy_itemList[random];
            array.push(item.id);
            let index_1 = copy_itemList.indexOf(item);
            if (index_1 > -1) {
                copy_itemList.splice(index_1, 1);
            }
            _number--;
        }

        return array;
    }

    static 获取关卡属性(_level) {
        let data = {
            level: _level,
            isWujin: false,
        }

        let isWujin = CardFunctions.是否是无尽模式(_level)
        if (isWujin) {
            let level = CardFunctions.获取当前关卡是无尽第几关(GameData.Get_CurrentLevel());
            data.isWujin = true;
            data.level = level;
        }
        else {
            data.isWujin = false;
            data.level = GameData.Get_CurrentLevel();
        }

        return data;
    }

    static 是否是无尽模式(_level) {
        let level = CardFunctions.获取当前关卡是无尽第几关(_level);
        if (level >= 0) {
            return true;
        }
        else {
            return false;
        }
    }
    static 获取当前关卡是无尽第几关(_level) {
        let number = _level - GameData.普通关卡数量;
        return number;
    }
    static 获取当前关卡是否是无尽第1关(_level) {
        let level = CardFunctions.获取当前关卡是无尽第几关(GameData.Get_CurrentLevel());
        return level === 0;
    }
    static 获取当前关卡的无尽种类关(_level) {
        let number = CardFunctions.获取当前关卡是无尽第几关(_level);
        let type = number % 3;
        return type;
    }
    static 获取当前无尽关卡的层数(_level) {
        let data = [7, 8, 9];
        let type = CardFunctions.获取当前关卡的无尽种类关(_level);
        let layer = data[type];
        return layer;
    }
    static 获取当前无尽关卡的阻挡数(_level) {
        let data = [0, 1, 2];
        let type = CardFunctions.获取当前关卡的无尽种类关(_level);
        let count = data[type];
        return count;
    }
    static 禁止操作(is禁止) {
        SS_NodeManager.Instance.不能操作.active = is禁止;
    }
    static async AD_callback(_callback: Function, _ad_scene: string) {
        let data = CardFunctions.获取关卡属性(GameData.Get_CurrentLevel())
        let isWujin = data.isWujin;
        let level = data.level;
        let model = isWujin ? "wujin" : "normal";

        let params = {
            ad_scene: _ad_scene,
            level: level + 1,
            model: model,
        };

        TAComponent.SendEvent(Consts.埋点事件.open_ad, params);

        await SS_UIManager.Instance.CreatePanel(`UI/WaitingPanel`, WaitingPanel);

        const isEnded = await AdMgr.Instance.showVideoAd();

        eventTarget.emit(GameEventData.广告结束);

        if (isEnded) {
            if (_callback) {
                _callback();
            }

            TAComponent.track('viewed_ad', { ad_scene: Consts.埋点事件.viewed_ad, params });
        } else {
            TAComponent.track('viewed_ad', { ad_scene: Consts.埋点事件.cancel_ad, params });
        }
    }

    static 初始三个id如果一样就交换() {
        let item_0 = GameData.currentLevelData_d[0];
        let item_1 = GameData.currentLevelData_d[1];
        let item_2 = GameData.currentLevelData_d[2];

        if (item_0.c === item_1.c && item_0.c === item_2.c) {

            let res_index = CardFunctions.查找俄罗斯方块数据中不等于id的index(2, item_2.c);
            if (res_index && res_index >= 0) {
                CommonFunction.Swap(GameData.currentLevelData_d, 2, res_index);
            }
        }
    }

    static 查找俄罗斯方块数据中不等于id的index(_index_from, _id) {
        let res = -1;

        for (let index = _index_from; index < GameData.currentLevelData_d.length; index++) {
            const data = GameData.currentLevelData_d[index];
            // console.log("blockGroup.c", data.c);

            if (data.c !== _id) {
                res = index;
                return res;
            }
        }

        return res;
    }

    static 防止三个一样的特殊交换() {
        let arr2 = CommonFunction.GroupByValue(GameData.arrCardGroups);
        // console.log(arr2);
        let result2 = arr2.find(item => item.length >= 2);
        // console.log("result2", result2);
        if (result2) {
            // console.log("result2[0].id", result2[0].id);
            let res_index = CardFunctions.查找俄罗斯方块数据中不等于id的index(GameData.currentBlockGroupCreateIndex, result2[0].id);
            // console.log("res", res_index);
            if (res_index && res_index >= 0) {
                CommonFunction.Swap(GameData.currentLevelData_d, GameData.currentBlockGroupCreateIndex, res_index);
            }
        }
    }

    // 判断一个点是否在以中心点 A 为中心的九宫格内
    static isInCenterGrid(pointX, pointY, centerX, centerY) {
        return pointX >= centerX - 1 && pointX <= centerX + 1 &&
            pointY >= centerY - 1 && pointY <= centerY + 1;
    }

    // 是否是同类
    static IsSameKind(id1, id2) {
        return id1 === id2;
    }

    // 是否全都下落了
    static async MainLoop() {
        let gameState: GameState = SS_GameManager.Instance.gameState;
        console.log(`gameState`, GameState[gameState]);

        if (gameState === GameState.三消开始) {
            if (GameData.arrLines && GameData.arrLines.length && GameData.arrLines.length >= 3) {
                //循环GameData.arrLine
                for (let i = 0; i < GameData.arrLines.length; i++) {
                    let grid = GameData.arrLines[i];
                    let card = CardFunctions.GetCard(grid.x, grid.y);
                    if (card) {
                        let index = GameData.arrCards.indexOf(card);
                        if (index >= 0) {
                            GameData.arrCards.splice(index, 1);
                        }
                        // if (GameData.arrCards.indexOf(card)) {
                        //     GameData.arrCards.splice(GameData.arrCards.indexOf(card), 1);
                        // }

                        card.node.destroy();
                    }
                }
            }

            GameData.arrLines = [];
            SS_Line.Instance.g.clear();

            SS_GameManager.Instance.gameState = GameState.新的生成;
            CardFunctions.MainLoop();


            // console.log(`是否满足三消`, CardFunctions.是否满足三消());
            // if (CardFunctions.是否满足三消()) {
            //     GameData.本回合是否完成消除 = true;
            //     // CardFunctions.KillAllSameList();
            //     await CardFunctions.KillAll3();
            //     SS_GameManager.Instance.gameState = GameState.下落开始;
            //     CardFunctions.MainLoop();
            // }
            // else {
            //     SS_GameManager.Instance.RoundEnd();
            //     // CardFunctions.消除后新生成();
            // }
        }
        else if (gameState === GameState.新的生成) {
            CardFunctions.消除后新生成();

            SS_GameManager.Instance.gameState = GameState.下落开始;
            CardFunctions.MainLoop();
        }
        else if (gameState === GameState.下落开始) {
            console.log(`下落开始`);
            // if (CardFunctions.是否可以下落()) {
            //     console.log(`可以下落`);
            await CardFunctions.全部下落();

            //     CardFunctions.MainLoop();
            // }
            // else {
            //     console.log(`不可以下落`);
            //     // GameManager.Instance.RoundEnd();
            //     CardFunctions.消除后新生成();

            //     await new Promise(res => SS_TimerManager.Instance.scheduleOnce(res, 0.1));
            //     SS_GameManager.Instance.gameState = GameState.三消开始;
            //     CardFunctions.MainLoop();
            // }
        }
    }

    static 消除后新生成() {
        let array = CardFunctions.获取所有空的grid();
        console.log(`array`, array);

        for (let index = 0; index < array.length; index++) {
            const grid: Grid = array[index];
            // grid.node.scale = 0.7;

            // let arr = GameData.wordList;
            // let id = arr[randomRangeInt(0, arr.length)].id;
            // let block1 = CardFunctions.CreateCard(grid.col, grid.row, 100, ColorType.normal, id);
            const id = CardFunctions.GetCardId();
            CardFunctions.CreateCard(grid.x, grid.y, id).then((card) => {
                GameData.arrCards.push(card);
            });
        }
    }

    static 获取所有空的grid() {
        let arr = [];

        for (let x = 0; x < GameData.col; x++) {
            for (let y = 0; y < GameData.row; y++) {
                const card: Card = CardFunctions.GetCard(x, y);
                const grid: Grid = CardFunctions.GetGrid(x, y);
                if (card === null) {
                    arr.push(grid);
                }
            }
        }

        return arr;
    }

    static async KillAll3() {
        // let arrxy = CardFunctions.GetAll3XY();
        // console.log(`arrxy`, arrxy);

        // for (let index = 0; index < arrxy.length; index++) {
        //     const arr = arrxy[index].array;
        //     console.log(`arr-------`, arr);

        //     for (let index = 0; index < arr.length; index++) {
        //         const block: Block = arr[index];
        //         // // block.node.active = false;
        //         // block.Destroy();

        //         // let grid = CardFunctions.GetGrid(block.col, block.row);
        //         // // console.log(block.col, block.row, grid);

        //         // grid.block = null;

        //         // if (index === 0) {
        //         //     block.升级();
        //         //     // grid.select.active = true;
        //         //     // let id = block.id;
        //         //     // let level = block.level + 1;
        //         //     // let block1 = CardFunctions.CreateBlock(grid.col, grid.row, 100, ColorType.normal, id, level);
        //         // }
        //         // else {
        //         // const block: Block = arr[index];
        //         // block.node.active = false;
        //         block.Destroy();
        //         // console.log(block);

        //         // let grid = CardFunctions.GetGrid(block.col, block.row);
        //         // console.log(block.col, block.row, grid);

        //         // grid.block = null;
        //         // }
        //     }
        // }

        // await new Promise(res => SS_TimerManager.Instance.scheduleOnce(res, 0.5));
    }

    public static 是否满足三消() {
        // let arrxy = CardFunctions.GetAll3XY();
        // if (arrxy.length > 0) {
        //     return true;
        // }

        return false;
    }

    /**
     * 获取普通消除数据
     */
    // static GetAll3XY() {
    //     const arrX = CardFunctions.GetAll3ArrayX();
    //     const arrY = CardFunctions.GetAll3ArrayY();
    //     console.log(`arrX`, arrX);
    //     console.log(`arrY`, arrY);

    //     let array_all: any = [];
    //     // array_all = arrX.concat(arrY);

    //     // console.log(`array_all`, array_all);
    //     // return array_all;

    //     for (let index_x = arrX.length - 1; index_x >= 0; index_x--) {
    //         const group_x: any[] = arrX[index_x];
    //         for (let index_y = arrY.length - 1; index_y >= 0; index_y--) {
    //             const group_y: any[] = arrY[index_y];

    //             // let superList = group_x.filter((t1) => group_y.some((t2) => t1.x == t2.x && t1.y == t2.y));
    //             // console.log(`res`, res[0].x, res[0].y);
    //             // console.log(`superList---`, superList);

    //             let isHave = group_x.some(item1 => group_y.includes(item1));
    //             // let res = superList.filter((t1) => GameData.ClickCardArray.some((t2) => t1.x == t2.x && t1.y == t2.y));
    //             // let xyCard;
    //             // if (res.length > 0) {
    //             //     xyCard = res[0];
    //             // } else {
    //             // xyCard = superList[0];
    //             // }

    //             // console.log(`res---`, superList);

    //             // if (superList.length > 0) {
    //             if (isHave) {
    //                 console.log(`找到`, index_x, index_y, group_x, group_y);
    //                 arrX.splice(index_x, 1);
    //                 arrY.splice(index_y, 1);

    //                 let arr_type = {
    //                     xNumber: group_x.length,
    //                     yNumber: group_y.length,
    //                     // xyCard: xyCard,
    //                     array: CardFunctions.ArrayQuChong(group_x.concat(group_y)),
    //                 };
    //                 array_all.push(arr_type);
    //             }
    //         }
    //     }

    //     for (let index_x = 0; index_x < arrX.length; index_x++) {
    //         const group_x: any[] = arrX[index_x];

    //         let arr_type = {
    //             xNumber: group_x.length,
    //             yNumber: 0,
    //             // xyCard: xyCard,
    //             array: group_x,
    //         };
    //         array_all.push(arr_type);
    //     }

    //     for (let index_y = 0; index_y < arrY.length; index_y++) {
    //         const group_y: any[] = arrY[index_y];


    //         let arr_type = {
    //             xNumber: 0,
    //             yNumber: group_y.length,
    //             // xyCard: xyCard,
    //             array: group_y,
    //         };
    //         array_all.push(arr_type);
    //     }

    //     console.log(`array_all`, array_all);
    //     return array_all;
    // }

    // // 横向
    // static GetAll3ArrayX() {
    //     let arr = [];

    //     let tempArray = [];

    //     let fun = () => {
    //         if (tempArray.length >= 3) {
    //             // let data = {
    //             //     type: GroupType.横,
    //             //     array: tempArray,
    //             //     length: tempArray.length,
    //             // }
    //             let data = tempArray;
    //             arr.push(data);
    //         }
    //         tempArray = [];
    //     };

    //     for (let y = 0; y < GameData.row; y++) {
    //         fun();
    //         for (let x = 0; x < GameData.col; x++) {
    //             const grid: Grid = CardFunctions.GetGrid(x, y);

    //             if (grid) {
    //                 if (grid.block) {
    //                     let block = grid.block;
    //                     const id = block.id;
    //                     const level = block.level;
    //                     let temp = tempArray[tempArray.length - 1];
    //                     if (!temp) {
    //                         tempArray.push(block);
    //                     } else {
    //                         if (temp.id === id && temp.level === level) {
    //                             tempArray.push(block);
    //                         } else {
    //                             fun();
    //                             tempArray.push(block);
    //                         }
    //                     }
    //                 } else {
    //                     fun();
    //                 }

    //                 if (x === GameData.col - 1 && y === GameData.row - 1) {
    //                     fun();
    //                 }
    //             } else {
    //                 fun();
    //             }
    //         }
    //     }

    //     return arr;
    // }

    // // 纵向
    // static GetAll3ArrayY() {
    //     let arr = [];

    //     let tempArray = [];

    //     let fun = () => {
    //         if (tempArray.length >= 3) {

    //             let data = tempArray;
    //             arr.push(data);
    //         }
    //         tempArray = [];
    //     };

    //     for (let x = 0; x < GameData.col; x++) {
    //         fun();
    //         for (let y = 0; y < GameData.row; y++) {
    //             const grid: Grid = CardFunctions.GetGrid(x, y);
    //             // const hasGrid = CardFunctions.HasGrid(x, y);
    //             // const notWord = scrCard.id < 100;
    //             // if (hasGrid && notWord) {
    //             if (grid) {
    //                 if (grid.block) {
    //                     let block = grid.block;
    //                     const id = block.id;
    //                     // const level = block.level;
    //                     let temp = tempArray[tempArray.length - 1];
    //                     if (!temp) {
    //                         tempArray.push(block);
    //                     } else {
    //                         if (temp.id === id && temp.level === level) {
    //                             tempArray.push(block);
    //                         } else {
    //                             fun();
    //                             tempArray.push(block);
    //                         }
    //                     }
    //                 } else {
    //                     fun();
    //                 }

    //                 if (x === GameData.col - 1 && y === GameData.row - 1) {
    //                     fun();
    //                 }
    //             } else {
    //                 fun();
    //             }
    //         }
    //     }

    //     return arr;
    // }

    // 数组去重复
    static ArrayQuChong(arr) {
        let s1 = new Set(arr);
        return Array.from(s1);
    }

    public static 是否可以下落() {
        for (let x = 0; x < GameData.col; x++) {
            for (let y = 0; y < GameData.row; y++) {
                // const scrGrid: Grid = CardFunctions.GetGrid(x, y);
                // GameData.arrGrids[x][y] = scrGrid;
                let target_grid = CardFunctions.获取目标grid(x, y);
                if (target_grid != null) {
                    return true;
                }
            }
        }

        return false;
    }

    public static 获取目标grid(_col, _row) {
        if (_row === 0) {
            return null;
        }

        let count = CardFunctions.获取当前下面有几个block(_col, _row);
        console.log(`count`, count);

        const current_grid: Grid = CardFunctions.GetGrid(_col, _row);
        const current_card: Card = CardFunctions.GetCard(_col, _row);
        const targetGrid: Grid = CardFunctions.GetGrid(_col, count);
        // console.log(`current_grid.block`, current_grid.block);

        if (current_card === null) {
            return null;
        }

        if (current_grid.y !== targetGrid.y) {
            return { grid: current_grid, targetGrid: targetGrid };
        }

        console.log(`获取目标grid`, null);

        return null;
    }

    public static 获取当前下面有几个block(_col, _row) {
        let count = 0;

        if (_row === 0) {
            return 0;
        }

        for (let row = _row - 1; row >= 0; row--) {
            const card: Card = CardFunctions.GetCard(_col, row);
            if (card) {
                count++;
            }
        }

        return count;
    }

    public static async 全部下落() {
        let duration = 0.2;
        for (let x = 0; x < GameData.col; x++) {
            for (let y = 0; y < GameData.row; y++) {
                const currentGrid: Grid = CardFunctions.GetGrid(x, y);
                // GameData.arrGrids[x][y] = scrGrid;
                let obj = CardFunctions.获取目标grid(x, y);
                if (obj != null) {
                    const targetGrid = obj.targetGrid;
                    targetGrid.block = currentGrid.block;
                    targetGrid.block.grid = targetGrid;
                    // targetGrid.block.node.y = targetGrid.node.y;
                    currentGrid.block = null;

                    // console.log(`targetGrid`, targetGrid, targetGrid.block, targetGrid.block.node);

                    targetGrid.block.y = targetGrid.y;
                    // targetGrid.block.node.y = targetGrid.block.grid.node.y


                    tween(targetGrid.block.node)
                        // .to(duration, {  y: targetGrid.block.grid.node.y })
                        .to(duration, { position: v3(targetGrid.block.grid.node.position.x, targetGrid.block.grid.node.position.y, 0) })
                        .call(() => {
                        })
                        .start()
                }
            }
        }

        await SS_TimerManager.AwaitTime(duration + 0.1);

    }

}

/** 调试 */
window["CardFunctions"] = CardFunctions;